package com.biz.primus.ms.member.service;

import com.biz.primus.base.exception.BizBusinessException;
import com.biz.primus.base.exception.BizParameterException;
import com.biz.primus.model.member.exception.UserException;
import com.biz.primus.model.member.exception.UserExceptionType;
import com.biz.primus.model.member.vo.MemberFavouriteVo;
import com.biz.primus.ms.base.service.AbstractBaseService;
import com.biz.primus.ms.member.dao.po.MemberFavourite;
import com.biz.primus.ms.member.dao.redis.MemberFavouriteRedisDao;
import com.biz.primus.ms.member.dao.repository.MemberFavouriteRepository;
import com.biz.primus.ms.member.dao.ro.MemberFavouriteRo;
import com.biz.primus.ms.member.trans.MemberFavouriteRoToMemberFavouriteVo;
import com.biz.primus.ms.member.trans.MemberFavouriteToMemberFavouriteRo;
import com.biz.primus.ms.member.trans.MemberFavouriteToMemberFavouriteVo;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.util.List;

/**
 * 收藏
 * @author jun.liu
 * @date 2017年10月23日
 * @reviewer
 * @see
 */
@Slf4j
@Service
public class MemberFavouriteService extends AbstractBaseService
{
    private final MemberFavouriteRedisDao memberFavouriteRedisDao;

    private final MemberFavouriteRepository memberFavouriteRepository;

    @Autowired
    public MemberFavouriteService(MemberFavouriteRedisDao memberFavouriteRedisDao, MemberFavouriteRepository memberFavouriteRepository)
    {
        this.memberFavouriteRedisDao = memberFavouriteRedisDao;
        this.memberFavouriteRepository = memberFavouriteRepository;
    }

    /**
     * 反转收藏商品
     * true 为收藏  false为未收藏
     * @param memberId
     * @param productCode
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Boolean toggleMemberFavouriteProduct(Long memberId, String productCode)
    {
        if (memberId == null|| memberId == 0L)
        {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        if (StringUtils.isBlank(productCode))
        {
            throw new UserException(UserExceptionType.FAVOURITE_PRODUCT_NULL);
        }
        MemberFavourite po = this.memberFavouriteRepository.findByMemberIdAndProductCode(memberId, productCode);
        if(po == null)
        {
            po = new MemberFavourite();
            po.setMemberId(memberId);
            po.setProductCode(productCode);
            //可以不设置 默认已经设置为没有删除 false
            po.setDeleteFlag(false);
        }
        else
        {
            po.setDeleteFlag(true);
            po.setUpdateTimestamp(new Timestamp(System.currentTimeMillis()));
        }
        saveOrUpdateUsingPoPKIncreament(memberFavouriteRepository, memberFavouriteRedisDao, po, new MemberFavouriteToMemberFavouriteRo());
        return !po.getDeleteFlag();
    }

    /**
     * 查询所有已经收藏的商品对象
     * @param memberId
     * @return
     */
    public List<MemberFavouriteVo> findByMemberFavouriteProduct(Long memberId)
    {
        if (memberId == null|| memberId == 0L)
        {
            throw new BizParameterException("memberId Parameter is null");
        }
        List<MemberFavourite> pos = this.memberFavouriteRepository.findByMemberIdAndDeleteFlag(memberId, false);
        if(pos == null)
        {
            throw new BizBusinessException("MemberFavourite query on memberId is null");
        }
        return Lists.transform(pos, new MemberFavouriteToMemberFavouriteVo());
    }

    /**
     * 分页查询所有已经收藏的商品对象
     * @param memberId
     * @return
     */
    public List<MemberFavouriteVo> findByMemberFavouriteProduct(Long memberId, Integer page, Integer size)
    {
        if (memberId == null|| memberId == 0L)
        {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        List<MemberFavouriteRo> ros = this.memberFavouriteRedisDao.findPageMemberFavProducts(memberId, page, size);
        if(ros == null)
        {
            throw new UserException(UserExceptionType.FAVOURITE_NULL);
        }
        return Lists.transform(ros, new MemberFavouriteRoToMemberFavouriteVo());
    }

    /**
     * 总的收藏数
     * @param memberId
     * @return
     */
    public Long findByMemberFavouriteProductTotals(Long memberId)
    {
        if (memberId == null|| memberId == 0L)
        {
            throw new BizParameterException("memberId Parameter is null");
        }
        return this.memberFavouriteRedisDao.getFavoriteIdsTotals(memberId);
    }

    /**
     * 清空户用户收藏商品
     * @author jun.liu
     * @param memberId
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public void cleanMemberFavouriteProduct(Long memberId)
    {
        if (memberId == null|| memberId == 0L)
        {
            throw new UserException(UserExceptionType.MEMBERID_NULL);
        }
        List<MemberFavourite> pos = this.memberFavouriteRepository.findByMemberIdAndDeleteFlag(memberId, false);
        if(pos == null)
        {
            throw new UserException(UserExceptionType.FAVOURITE_NULL);
        }
        for(MemberFavourite po : pos)
        {
            po.setDeleteFlag(true);
            po.setUpdateTimestamp(new Timestamp(System.currentTimeMillis()));
        }
        batchSaveOrUpdateUsingPoPKIncreament(memberFavouriteRepository, memberFavouriteRedisDao, pos, new MemberFavouriteToMemberFavouriteRo());
    }

    /**
     * 批量删除  这里其实只是修改对象中的删除标识 所有实质还是进行的批量保存
     * @param memberId
     * @param productCodes
     */
    public void delete(Long memberId, List<String> productCodes) {
        List<MemberFavourite> favoriteProducts = memberFavouriteRepository.findByMemberIdAndProductCodeIn(memberId, productCodes);
        for (MemberFavourite favoriteProduct : favoriteProducts) {
            favoriteProduct.setDeleteFlag(true);
        }
        batchSaveOrUpdateUsingPoPKIncreament(memberFavouriteRepository, memberFavouriteRedisDao, favoriteProducts, new MemberFavouriteToMemberFavouriteRo());
    }

}
